Repository navigation
An idle chat on a paired computer hands its hold to the relay, and opening it elsewhere takes it - #2287
Draft
AbirAbbas wants to merge 21 commits into
Draft
An idle chat on a paired computer hands its hold to the relay, and opening it elsewhere takes it#2287AbirAbbas wants to merge 21 commits into
AbirAbbas wants to merge 21 commits into
Conversation
…is on the relay When a chat on a computer that shares its identity with another goes idle, its saved state (turns, settings, workspace, vault) is certified and uploaded outside the admission lock, then the hold is released in a short bounded step. Running, queued, starting or parked work keeps the hold. New work takes the hold back in place, or is refused if another computer took the chat. A home with one device makes no new requests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t asking A chat whose hold was released or has lapsed is marked openable in the list, only for paired homes and only from the directory's own clock. Opening it fetches and takes it with a non-forcing conditional acquire, checked again at acquisition, so a holder that renews during the fetch keeps the chat. A live hold still offers Continue here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a free chat directly An ordinary message in the window that released the chat reacquires the hold through the work gate: no restore, no setup question, and local files such as node_modules stay. A Home row for a free chat pulls the newest saved head even when an older viewer of it is open here. Remote pre-send checks honour the caller's deadline. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eleased chat back Rows carry an optional can_open. agents.open with a shared chat's id takes a free chat without the Continue-here step. Sends, queues, steers, retries and actions in a window that released its chat take the hold back first; app queues and actions count as work, so they keep the hold. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t moves The copy bucket was "copy-" plus the origin's full encoded path, so a chat moving back and forth nested the name and failed with 'file name too long' on the third hop. A chat that already has a local root keeps it, an origin that is itself a copy reuses its own name, and longer names are capped at 240 bytes with a stable hash. Existing short names are unchanged. This predates the idle hand-off, which makes repeated moves common. (The filing code moved to internal/syncsetup/copy_filing.go in the previous commits.) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Describe idle release, opening a free chat directly, take-back in the same window, and that a running chat still asks. Add the change entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The lock-defer law keeps an absorbed panic from becoming a deadlock. The open-row lookup and the live drive's idle checks now read under a helper that unlocks from a defer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ver undoes a take-back The terminal seals through the warm native daemon, whose capture plan is metadata-only, so the saved-state proof refused it and the hold was renewed forever. Certification now asks for a complete standalone plan; ordinary sealing stays on the daemon. A lost optimistic comparison or a competing local vault round retries at the quiet cadence. Ownership notices carry a version, so a release notice delivered after a newer acquisition is dropped. A held writer whose fresh ownership read fails keeps working offline, as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only the idle-release vault step uses the non-blocking lock. An ordinary SyncState waits under its own context, as on the base. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A nested project under a received copy keeps its own bucket, and the long-name hash is taken from the original path rather than the lossy encoded one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d first Adds the real-terminal test: openV3Agent and runSurface with the default native daemon, an on-disk relay and two homes, asserting release, in-place take-back and that effort and memory set after the last turn reach the other computer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…wnership door Effort, model choices, approval posture, places, task effort and a remembered note retake the hold or get the held-elsewhere refusal before they are saved, so a save is never acknowledged where it cannot reach the relay. Unpaired and unreleased windows keep their old path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ars a stale release snapshot A canceled or expired Close budget skipped the base cleanup and left an ordinary writer running; Close now keeps the idle-join error and always runs the capture, stop, cancel and join it ran before. A zero send receipt from the release is discarded once a reacquire has cleared the viewer, so a send after take-back is no longer refused as "available to continue here". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ld first Rename, rewind, task rooms, deletes and merges, plan steering, autonomy, names, anchors, standing tree and remembered notes enter the same released-window door before they write, so none is acknowledged where it cannot reach the relay. Every other window returns to its old path before any network read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Beyond 20,000 paths, 50,000 entries or 64 MiB of chat files the proof fails and the chat keeps its hold, as before this change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
An idle chat on a paired computer now hands its hold to the relay. Opening it on another paired computer takes it over without the Continue-here step, even when the first computer is off. A running chat still asks, so you can watch it without taking it.
Base is
app/v3, notdev. The take-back path this builds on exists only onapp/v3: ConfirmWork reacquire (#2186, #2180, #1991) and the desktop engine. This change reachesdevat the nextapp/v3↔devmerge.What changes
!shell) retakes the hold through the existing work gate. There is no restore, no setup question, and local files such asnode_modulesstay. If another computer took the chat, the work gets today's held-elsewhere refusal and nothing is written.can_open. It is set only for paired homes, and only from the directory's own lease expiry. Opening such a chat in the terminal, or throughagents.openwith its id, fetches the newest saved head and takes it with a non-forcing conditional acquire, checked again at acquisition. A live hold keeps the Continue-here choice. Rebuildable files are not carried, as today.copy-plus the origin's full encoded path, so a chat moving back and forth nested the name and failed withfile name too longon the third hop. Existing roots are kept, a copy origin reuses its own name, and longer names are capped at 240 bytes with a stable hash. Existing short names are unchanged.Nothing changes for anyone else
can_openis optional andomitempty, and the lease rules and wire are unchanged.Validation contract
C1. A paired, idle chat with its turns uploaded is released within a few seconds; the directory shows no live holder.
C2. A running turn, queued work, a running, starting or parked task or job, or unsent turns keep the hold, renewed as today.
C3. New work in the released window, when nobody else took the chat, retakes it before any write or model call, with no prompt.
C4. If another computer took it, new work gets the held-elsewhere refusal and nothing is written locally.
C5. Nothing is lost. Turns, journal, workspace (minus rebuildable files), memory and settings are on the relay before the release, and a failed upload keeps the hold.
C6. Opening a released or lapsed chat on another paired computer pulls and takes it with no Continue-here prompt; its state matches the last save.
C7. Opening a chat another computer holds behaves as today: you can watch, and Continue here stays the person's choice.
C8. C6 works while the first computer is stopped.
C9. Rebuildable files are not part of the hand-off.
C10. Unpaired and single-device homes behave exactly as before.
C11. Old builds on either side keep working.
C12. A send racing an open ends with exactly one owner under today's fencing.
Each item maps to
TestIdleRelease_C*/TestIdleOpen_C*tests in cellsync, cellstore, session, syncsetup, chatlist, handoff, tui3 and cmd/codeaf. All run five times.Verification
-race -count=3. Build, vet, gofmt, the manual gates, carried help and belt pages also pass.make test-laws: the lock-defer law caught three new sections, now fixed. The remaining reds fail identically on the basef7422fb8eand name no file in this change (commentlaw on factory copy, session complexity rows, taxonomy in factory).node_modulesexcluded.TestOwnershipCheckThatFindsAnotherHolderKeepsUnsentTurnsfails on cleanf7422fb8e.Not in this PR
can_openrow directly. That will be a separatecodeaf-deskPR. Until then the desktop keeps showing Continue here, which still works.🤖 Generated with Claude Code